package com.xuanxu.blogs.module.article.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuanxu.blogs.framework.common.exception.MissRequestParameterException;
import com.xuanxu.blogs.module.article.entity.dao.ArticleClassifyDao;
import com.xuanxu.blogs.module.article.entity.po.ArticleClassify;
import com.xuanxu.blogs.module.article.exception.ArticleClassifyAlreadyExistException;
import com.xuanxu.blogs.module.article.mapper.ArticleClassifyMapper;
import com.xuanxu.blogs.module.article.service.ArticleClassifyService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

import static com.xuanxu.blogs.module.article.enums.ArticleHttpStatusEnum.ARTICLE_CLASSIFY_ALREADY_EXIST;

/**
 * @author XuanXu
 * @version 1.0
 * @date 2024-08-21 15:32
 */
@Service
@RequiredArgsConstructor
public class ArticleClassifyServiceImpl implements ArticleClassifyService {
    private final ArticleClassifyMapper articleClassifyMapper;

    @Override
    public IPage<ArticleClassifyDao> pageSelectArticleClassify(Long currentPage, Long pageSize,
                                                               ArticleClassifyDao articleClassifyDao) {
        LambdaQueryWrapper<ArticleClassify> articleClassifyLambdaQueryWrapper = constructionSelectionCondition(articleClassifyDao);
        IPage<ArticleClassify> articleClassifyPage = articleClassifyMapper.selectPage(new Page<>(currentPage, pageSize), articleClassifyLambdaQueryWrapper);

        Page<ArticleClassifyDao> articleClassifyDaoPage = new Page<>();
        BeanUtil.copyProperties(articleClassifyPage, articleClassifyDaoPage);
        if (articleClassifyPage != null) {
            List<ArticleClassifyDao> articleClassifyDaoList = BeanUtil.copyToList(articleClassifyPage.getRecords(), ArticleClassifyDao.class);
            articleClassifyDaoPage.setRecords(articleClassifyDaoList);
        }

        return articleClassifyDaoPage;
    }

    @Override
    public boolean insertArticleClassify(ArticleClassifyDao articleClassifyDao) {
        if (articleClassifyDao == null) {
            return false;
        }

        verifyArticleClassifyIsExist(articleClassifyDao);

        ArticleClassify articleClassify = BeanUtil.copyProperties(articleClassifyDao, ArticleClassify.class);
        int insertNumber = articleClassifyMapper.insert(articleClassify);
        return insertNumber > 0;
    }

    @Override
    public boolean updateArticleClassifyById(ArticleClassifyDao articleClassifyDao) {
        if (articleClassifyDao == null || articleClassifyDao.getArticleClassifyId() == null) {
            return false;
        }

        verifyArticleClassifyIsExist(articleClassifyDao);

        LambdaUpdateWrapper<ArticleClassify> articleClassifyLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        articleClassifyLambdaUpdateWrapper.set(StrUtil.isNotEmpty(articleClassifyDao.getArticleClassifyName()),
                ArticleClassify::getArticleClassifyName, articleClassifyDao.getArticleClassifyName());
        articleClassifyLambdaUpdateWrapper.eq(ArticleClassify::getArticleClassifyId,
                articleClassifyDao.getArticleClassifyId());

        int updateNumber = articleClassifyMapper.update(articleClassifyLambdaUpdateWrapper);
        return updateNumber > 0;
    }

    @Override
    public boolean deleteArticleClassifyById(Long articleClassifyId) {
        if (articleClassifyId == null) {
            return false;
        }

        // TODO 会绑定文章，需要先判断是否绑定了
        int deleteNumber = articleClassifyMapper.deleteById(articleClassifyId);
        return deleteNumber > 0;
    }

    @Override
    public boolean batchDeleteArticleClassifyById(List<Long> articleClassifyIdList) {
        if (articleClassifyIdList == null || articleClassifyIdList.isEmpty()) {
            return false;
        }

        // TODO 会绑定文章，需要先判断是否绑定了
        int deleteNumber = articleClassifyMapper.deleteBatchIds(articleClassifyIdList);
        return deleteNumber > 0;
    }

    @Override
    public List<ArticleClassifyDao> selectArticleClassifyByArticleClassifyId(List<Long> articleClassifyIdList) {
        if (articleClassifyIdList == null || articleClassifyIdList.isEmpty()) {
            return null;
        }

        LambdaQueryWrapper<ArticleClassify> articleClassifyLambdaQueryWrapper = new LambdaQueryWrapper<>();
        articleClassifyLambdaQueryWrapper.in(ArticleClassify::getArticleClassifyId, articleClassifyIdList);
        List<ArticleClassify> articleClassifyList = articleClassifyMapper.selectList(articleClassifyLambdaQueryWrapper);
        return BeanUtil.copyToList(articleClassifyList, ArticleClassifyDao.class);
    }

    @Override
    public List<ArticleClassifyDao> selectArticleClassify(ArticleClassifyDao articleClassifyDao) {
        LambdaQueryWrapper<ArticleClassify> articleClassifyLambdaQueryWrapper = constructionSelectionCondition(articleClassifyDao);
        List<ArticleClassify> articleClassifyList = articleClassifyMapper.selectList(articleClassifyLambdaQueryWrapper);
        return BeanUtil.copyToList(articleClassifyList, ArticleClassifyDao.class);
    }


    /**
     * 校验文章分类是否存在
     * @param articleClassifyDao 文章分类 dao
     */
    private void verifyArticleClassifyIsExist(ArticleClassifyDao articleClassifyDao) {
        if (articleClassifyDao == null) {
            return;
        }

        verifyArticleClassifyNameIsExist(articleClassifyDao.getArticleClassifyId(), articleClassifyDao.getArticleClassifyName());
    }

    /**
     * 验证文章分类名称是否存在
     * @param articleClassifyId 文章分类ID
     * @param articleClassifyName 文章分类名称
     */
    private void verifyArticleClassifyNameIsExist(Long articleClassifyId, String articleClassifyName) {
        if (StrUtil.isEmpty(articleClassifyName)) {
            throw new MissRequestParameterException();
        }

        LambdaQueryWrapper<ArticleClassify> articleClassifyLambdaQueryWrapper = new LambdaQueryWrapper<>();
        articleClassifyLambdaQueryWrapper.eq(ArticleClassify::getArticleClassifyName, articleClassifyName);
        ArticleClassify articleClassify = articleClassifyMapper.selectOne(articleClassifyLambdaQueryWrapper);
        if (articleClassify == null) {
            return;
        }

        if (articleClassifyId != null && Objects.equals(articleClassifyId, articleClassify.getArticleClassifyId())) {
            return;
        }

        throw new ArticleClassifyAlreadyExistException(ARTICLE_CLASSIFY_ALREADY_EXIST);
    }

    /**
     * 构造查询条件
     * @param articleClassifyDao 文章分类 dao 对象
     * @return LambdaQueryWrapper
     */
    private LambdaQueryWrapper<ArticleClassify> constructionSelectionCondition(ArticleClassifyDao articleClassifyDao) {
        LambdaQueryWrapper<ArticleClassify> articleClassifyLambdaQueryWrapper = new LambdaQueryWrapper<>();

        if (articleClassifyDao == null) {
            return articleClassifyLambdaQueryWrapper;
        }

        articleClassifyLambdaQueryWrapper.eq(articleClassifyDao.getArticleClassifyId() != null,
                ArticleClassify::getArticleClassifyId, articleClassifyDao.getArticleClassifyId());
        articleClassifyLambdaQueryWrapper.like(StrUtil.isNotEmpty(articleClassifyDao.getArticleClassifyName()),
                ArticleClassify::getArticleClassifyName, articleClassifyDao.getArticleClassifyName());

        articleClassifyLambdaQueryWrapper.orderByDesc(ArticleClassify::getUpdateTime);
        return articleClassifyLambdaQueryWrapper;
    }
}
